/**
 * \file test.cpp
 * \brief DES example and test
 * \author Wouter Caarls <w.caarls@tudelft.nl> 
 *
 * \verbatim
 * Copyright (c) 2005-7 Wouter Caarls, Delft University of Technology
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * \endverbatim
 */

#include <iostream>
#include "des.hpp"
#include "devices.hpp"

#include <stdio.h>

DESsignal mySignal1, mySignal2;

class CDummyProcess : public DESprocess
{
public:

  CDummyProcess(void *arg) : DESprocess("CDummyProcess", arg) { }

  void main(void *arg)
  {
    printf("(p1) Starting signal process\n");

    for (int i=0; i < 100000; i++)
    {
      wait(2);
      mySignal1.signal();
    }

    printf("(p1) exiting\n");
  }
};

class CDummyProcess2 : public DESprocess
{
public:

  CDummyProcess2(void *arg) : DESprocess("CDummyProcess2", arg) { }

  void main(void *arg)
  {
    printf("(p2) Starting wait process\n");

    for (int i=0; 1; i++)
    {
      wait(&mySignal1);
      wait(1);
    }
  }
};

class CDummyThread : public DESthread
{
public:

  CDummyThread(void *arg) : DESthread("CDummyThread", arg) { }

  void main(void *arg)
  {
    printf("(r1) Starting signal process\n");

    for (int i=0; i < 100000; i++)
    {
      wait(2);
      mySignal2.signal();
      sleep(2);
    }

    printf("(r1) exiting\n");
  }
};

class CDummyThread2 : public DESthread
{
public:

  CDummyThread2(void *arg) : DESthread("CDummyThread2", arg) { }

  void main(void *arg)
  {
    printf("(r2) Starting wait process\n");

    for (int i=0; 1; i++)
    {
      wait(&mySignal2);
      wait(1);
    }
  }
};

int main(int argc, char **argv)
{
  DESparallelDevice device1("device1");
  CDummyProcess process1((void*)42);
  CDummyProcess2 process2((void*)42);

  DESroundRobinDevice device2("device2");
  CDummyThread thread1((void*)42);
  CDummyThread2 thread2((void*)42);

  DESopenTrace("test.lxt");

  device1.addProcess(&process1);
  device1.addProcess(&process2);

  device2.addProcess(&thread1);
  device2.addProcess(&thread2);

  TIME time = DESrun();

  DEScloseTrace();
  
  std::cout << "Simulation stopped after " << time << " timesteps" << std::endl;

  std::cout << "Round robin device was busy for " << device2.getProcessedTime() << " timesteps" << std::endl;


  return 0;
}
